#include "GUI.h"
#include "SpriteBatch.h"
#include "BitmapFont.h"
#include "Colors.h"

#define DEFAULT_GUI_TEXTURE_NAME "DefaultGUITexture"
#define DEFAULT_GUI_TEXTURE_FILENAME "DefaultGUITexture.png"
#define DEFAULT_GUI_FONT_FILENAME "impact.fnt"

namespace Cvekas {

/// \brief Visual parameters of DefaultGUIStyle
///
/// It is possible to radically change GUI look only by providing 
///	custom DefaultGUIStyleDesc to DefaultGUI.
struct DefaultGUIStyleDesc
{
	BitmapFontPtr font;
	Texture2DPtr texture;
	Color text_color;

	RectF src_button_up, src_button_down;
	RectF src_switch_up, src_switch_down;
	RectF src_slider, src_slider_knob_up, src_slider_knob_down;
	RectF src_selector;
	RectF src_selector_prev_up, src_selector_prev_down;
	RectF src_selector_next_up, src_selector_next_down;
	RectF src_pointer;
};

/// Default implementation of GUIStyle
class DefaultGUIStyle : public GUIStyle
{
public:
	DefaultGUIStyle(SpriteBatchPtr sprite_batch, uint layer = 0);

	DefaultGUIStyle(SpriteBatchPtr sprite_batch, DefaultGUIStyleDesc& desc, uint layer = 0);

	~DefaultGUIStyle();

	virtual bool hitButton(const Vector2& pos, const std::string& text);
	virtual bool hitSwitch(const Vector2& pos, const std::string& text);
	virtual float hitSlider(const Vector2& pos);
	virtual bool hitSelector(const Vector2& pos, const std::vector<std::string>& selections, uint& button);

	virtual void drawLabel(const Vector2& pos, const std::string& text);
	virtual void drawButton(const Vector2& pos, const std::string& text, bool mouse_over, bool pressed);
	virtual void drawSwitch(const Vector2& pos, const std::string& text, bool mouse_over, bool state);
	virtual void drawSlider(const Vector2& pos, bool mouse_over, float state);
	virtual void drawSelector(const Vector2& pos, const std::vector<std::string>& selections, uint item, 
		bool mouse_over, bool mouse_over_prev, bool mouse_over_next, bool pressed);

	virtual void endFrame();

private:
	struct SelectorStyleState
	{
		float prev_blend;
		float next_blend;
	};

	union WidgetStyleState
	{
		float blend; // button, switch, slider
		SelectorStyleState selector;
	};

	bool validateDesc();

	DefaultGUIStyleDesc desc;
	SpriteBatchPtr sprite_batch;
	uint layer;

	StaticHashMap<WidgetStyleState, uint, GUI::cache_size> cache;
};

typedef boost::shared_ptr<DefaultGUIStyle> DefaultGUIStylePtr;

} // namespace